package com.base.app_core.service.Retrofit;

import com.base.app_core.base.BaseView;
import com.base.app_core.service.rx.Callback;
import com.base.app_core.util.AppConstants;
import com.base.app_core.util.ErrorType;
import com.base.app_core.util.log.F;
import com.base.app_core.util.retrofit.MyRequestBodyConverter;
import com.blankj.utilcode.util.NetworkUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;


/**
 * Created by xiangheng.song on 2017/2/28.
 */

public class HttpUtils {

    private static final int TIMEOUT = 5;
    private static Retrofit retrofit;
    private static Map<Class<?>, Object> serviceMap = new HashMap<>();

    static {
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        clientBuilder.connectTimeout(TIMEOUT, TimeUnit.SECONDS);    // 超时时间5s
        clientBuilder.cookieJar(new CookieJar() {
            @Override
            public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
                // TODO save cookies
            }

            @Override
            public List<Cookie> loadForRequest(HttpUrl url) {
                return null;
            }
        });

        // session 相关
//        clientBuilder.addInterceptor(new AppendCookiesInterceptor());
//        clientBuilder.addInterceptor(new SaveCookiesInterceptor());
        retrofit = new Retrofit.Builder().client(clientBuilder.build())
                .addConverterFactory(MyRequestBodyConverter.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(AppConstants.SERVER_URL)
                .build();
    }

    public static <T> T get(Class<T> clazz) {
        Object service = serviceMap.get(clazz);
        if (service == null) {
            service = retrofit.create(clazz);
            serviceMap.put(clazz, service);
        }
        return (T) service;
    }

    public static <T> void invoke(BaseView lifecycle, Observable<HttpResult<T>> observable, Callback<T> callback) {

        /**
         * 先判断网络连接状态和网络是否可用，放在回调那里好呢，还是放这里每次请求都去判断下网络是否可用好呢？
         * 如果放在请求前面太耗时了，如果放回掉提示的速度慢，要10秒钟请求超时后才提示。
         * 最后采取的方法是判断网络是否连接放在外面，网络是否可用放在回掉。
         */
        if (!NetworkUtils.isConnected()) {
            if (lifecycle != null) {
                lifecycle.notifyError(ErrorType.NET_WORK_ERROR.getCode(), ErrorType.NET_WORK_ERROR.getMessage());
            }
            return;
        }
        F.j("invoke");
        callback.setTarget(lifecycle);
//        Subscription subscription =
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(callback);
        F.j("1333");
//        lifecycle.bindToLifecycle(subscription);
    }

//    public static <T> void invoke(Observable<HttpResult<T>> observable, Callback<T> callback) {
//        observable.subscribeOn(Schedulers.io())
//                .observeOn(AndroidSchedulers.mainThread())
//                .subscribe(callback);
//    }
}
